<template>
  <view class="custom-department-picker">
    <!-- 输入框显示区域 -->
    <view class="picker-input" @click="showPicker">
      <text v-if="selectedText" class="selected-text">{{ selectedText }}</text>
      <text v-else class="placeholder">{{ placeholder }}</text>
      <uni-icons type="down" size="16" color="#999" />
    </view>

    <!-- 弹出层 -->
    <uni-popup
      ref="popup"
      type="bottom"
      :safe-area="false"
      @change="handlePopupChange"
    >
      <view class="picker-popup">
        <view class="popup-header">
          <text class="popup-title">{{ popupTitle }}</text>
          <text class="close-btn" @click="hidePicker">✕</text>
        </view>

        <scroll-view class="popup-content" scroll-y>
          <view class="department-list">
            <template v-for="item in flatDepartmentList" :key="item.id">
              <view
                class="department-item"
                :style="{ paddingLeft: item.level * 20 + 15 + 'px' }"
              >
                <!-- Radio 按钮 -->
                <radio
                  :checked="tempSelectedValue === item.value"
                  @click="selectDepartment(item)"
                  color="#007aff"
                />

                <!-- 部门名称 -->
                <text
                  class="department-name"
                  :class="{ 'has-children': item.hasChildren }"
                  @click="toggleExpand(item)"
                >
                  {{ item.text }}
                </text>

                <!-- 展开/收起图标 -->
                <uni-icons
                  v-if="item.hasChildren"
                  type="down"
                  size="20"
                  color="#999"
                  :class="['expand-icon', { expanded: item.expanded }]"
                  @click="toggleExpand(item)"
                />
              </view>
            </template>
          </view>
        </scroll-view>

        <view class="popup-footer">
          <button class="cancel-btn" @click="hidePicker">取消</button>
          <button class="confirm-btn" @click="confirmSelection">确定</button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, watch } from "vue";

interface DepartmentItem {
  id: string;
  value: string;
  text: string;
  parentId?: string;
  level: number;
  hasChildren: boolean;
  expanded: boolean;
  children?: DepartmentItem[];
  originalData?: any;
}

interface Props {
  modelValue?: string;
  placeholder?: string;
  popupTitle?: string;
  departmentData?: any[];
}

interface Emits {
  (e: "update:modelValue", value: string): void;
  (e: "change", value: string, item: DepartmentItem): void;
  (e: "popup-open"): void;
  (e: "popup-close"): void;
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: "请选择部门",
  popupTitle: "请选择所属部门",
  departmentData: () => [],
});

const emits = defineEmits<Emits>();

const popup = ref<any>(null);
const selectedValue = ref<string>(props.modelValue || "");
const selectedText = ref<string>("");
const departmentTree = ref<DepartmentItem[]>([]);

// 临时选择状态（用于延迟确认）
const tempSelectedValue = ref<string>("");
const tempSelectedText = ref<string>("");

// 扁平化的部门列表（用于显示）
const flatDepartmentList = computed(() => {
  const result: DepartmentItem[] = [];

  const flatten = (items: DepartmentItem[], level = 0) => {
    items.forEach((item) => {
      result.push({ ...item, level });

      if (item.hasChildren && item.expanded && item.children) {
        flatten(item.children, level + 1);
      }
    });
  };

  flatten(departmentTree.value);
  return result;
});

// 转换部门数据为树形结构（提前定义，避免作用域问题）
const convertToDepartmentTree = (data: any[]): DepartmentItem[] => {
  const convertItem = (item: any): DepartmentItem => {
    const hasChildren =
      item.Children && Array.isArray(item.Children) && item.Children.length > 0;

    return {
      id: item.Id || item.Value,
      value: item.Value || item.Id,
      text: item.Text || item.Tag,
      parentId: item.ParentId,
      level: 0,
      hasChildren,
      expanded: false,
      children: hasChildren ? item.Children.map(convertItem) : [],
      originalData: item,
    };
  };

  return data.map(convertItem);
};

// 更新选中文本 - 显示完整路径（提前定义，避免作用域问题）
const updateSelectedText = () => {
  if (!selectedValue.value) {
    selectedText.value = "";
    return;
  }

  // 查找选中项目并构建路径
  const findItemWithPath = (
    items: DepartmentItem[],
    path: string[] = [],
  ): { item: DepartmentItem | null; fullPath: string[] } => {
    for (const item of items) {
      const currentPath = [...path, item.text];

      if (item.value === selectedValue.value) {
        return { item, fullPath: currentPath };
      }

      if (item.children && item.children.length > 0) {
        const result = findItemWithPath(item.children, currentPath);
        if (result.item) {
          return result;
        }
      }
    }
    return { item: null, fullPath: [] };
  };

  const result = findItemWithPath(departmentTree.value);
  if (result.item && result.fullPath.length > 0) {
    // 使用 "/" 连接路径，显示完整的部门层级
    selectedText.value = result.fullPath.join("/");
  } else {
    selectedText.value = "";
  }
};

// 更新临时选中文本 - 显示完整路径（提前定义，避免作用域问题）
const updateTempSelectedText = () => {
  if (!tempSelectedValue.value) {
    tempSelectedText.value = "";
    return;
  }

  // 查找选中项目并构建路径
  const findItemWithPath = (
    items: DepartmentItem[],
    path: string[] = [],
  ): { item: DepartmentItem | null; fullPath: string[] } => {
    for (const item of items) {
      const currentPath = [...path, item.text];

      if (item.value === tempSelectedValue.value) {
        return { item, fullPath: currentPath };
      }

      if (item.children && item.children.length > 0) {
        const result = findItemWithPath(item.children, currentPath);
        if (result.item) {
          return result;
        }
      }
    }
    return { item: null, fullPath: [] };
  };

  const result = findItemWithPath(departmentTree.value);
  if (result.item && result.fullPath.length > 0) {
    // 使用 "/" 连接路径，显示完整的部门层级
    tempSelectedText.value = result.fullPath.join("/");
  } else {
    tempSelectedText.value = "";
  }
};

// 监听 modelValue 变化
watch(
  () => props.modelValue,
  (newValue) => {
    selectedValue.value = newValue || "";
    updateSelectedText();
  },
);

// 监听部门数据变化
watch(
  () => props.departmentData,
  (newData) => {
    if (newData && newData.length > 0) {
      try {
        const treeData = convertToDepartmentTree(newData);
        departmentTree.value = treeData;
        updateSelectedText();
      } catch (error) {
        console.error("部门数据转换失败:", error);
        departmentTree.value = [];
      }
    } else {
      // 如果数据为空，清空树形结构
      departmentTree.value = [];
    }
  },
  { immediate: true, deep: true },
);

// 切换展开/收起（提前定义，避免作用域问题）
const toggleExpand = (item: DepartmentItem) => {
  if (!item.hasChildren) return;

  // 在原始数据中切换展开状态
  const toggleInTree = (items: DepartmentItem[]) => {
    items.forEach((treeItem) => {
      if (treeItem.id === item.id) {
        treeItem.expanded = !treeItem.expanded;
      }
      if (treeItem.children) {
        toggleInTree(treeItem.children);
      }
    });
  };

  toggleInTree(departmentTree.value);
};

// 手风琴展开效果：展开选中项，收起同级其他项（提前定义，避免作用域问题）
const expandWithAccordionEffect = (targetItem: DepartmentItem) => {
  // 找到目标项的父级，然后收起同级的其他项，展开目标项
  const processAccordion = (items: DepartmentItem[]) => {
    items.forEach((item) => {
      // 如果是目标项，展开它
      if (item.id === targetItem.id) {
        item.expanded = true;
      }
      // 如果是同级的其他项（有相同的父级），收起它们
      else if (item.parentId === targetItem.parentId && item.hasChildren) {
        item.expanded = false;
      }

      // 递归处理子项
      if (item.children && item.children.length > 0) {
        processAccordion(item.children);
      }
    });
  };

  processAccordion(departmentTree.value);
};

// 选择部门（仅更新临时状态，不触发事件）（提前定义，避免作用域问题）
const selectDepartment = (item: DepartmentItem) => {
  tempSelectedValue.value = item.value;

  // 更新临时显示文本为完整路径
  updateTempSelectedText();

  // 手风琴效果：如果选中的部门有子部门，则展开它，同时收起其他同级部门
  if (item.hasChildren) {
    expandWithAccordionEffect(item);
  }

  // 注意：不再立即触发事件，只有在确认时才会触发
};

// 显示选择器
const showPicker = () => {
  // 初始化临时选择状态为当前值
  tempSelectedValue.value = selectedValue.value;
  tempSelectedText.value = selectedText.value;

  if (popup.value) {
    popup.value.open();
  }
};

// 隐藏选择器（取消操作，恢复到原始状态）
const hidePicker = () => {
  // 恢复临时状态到原始值
  tempSelectedValue.value = selectedValue.value;
  tempSelectedText.value = selectedText.value;

  if (popup.value) {
    popup.value.close();
  }
};

// 确认选择
const confirmSelection = () => {
  // 如果有临时选择，则提交更改
  if (tempSelectedValue.value) {
    // 将临时状态提交为正式状态
    selectedValue.value = tempSelectedValue.value;
    selectedText.value = tempSelectedText.value;

    // 查找选中的部门项，用于触发 change 事件
    const findSelectedItem = (
      items: DepartmentItem[],
    ): DepartmentItem | null => {
      for (const item of items) {
        if (item.value === selectedValue.value) {
          return item;
        }
        if (item.children && item.children.length > 0) {
          const result = findSelectedItem(item.children);
          if (result) {
            return result;
          }
        }
      }
      return null;
    };

    const selectedItem = findSelectedItem(departmentTree.value);

    // 触发事件，通知外部组件
    emits("update:modelValue", selectedValue.value);
    if (selectedItem) {
      emits("change", selectedValue.value, selectedItem);
    }
  } else {
    // 如果没有临时选择，则清空现有选择
    selectedValue.value = "";
    selectedText.value = "";
    emits("update:modelValue", "");
  }

  // 关闭选择器
  if (popup.value) {
    popup.value.close();
  }
};

// 处理弹框状态变化
const handlePopupChange = (e: any) => {
  // e.show 为 true 表示弹框打开，false 表示弹框关闭
  if (e.show) {
    emits("popup-open");
  } else {
    emits("popup-close");
  }
};
</script>

<style scoped>
.custom-department-picker {
  width: 100%;
}

.picker-input {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14rpx 20rpx;
  border: 2rpx solid #e5e5e5;
  border-radius: 12rpx;
  background-color: #fff;
  min-height: 40rpx;
  box-sizing: border-box;
}

.selected-text {
  color: #333;
  flex: 1;
  font-size: 26rpx;
}

.placeholder {
  color: #999;
  flex: 1;
  font-size: 28rpx;
}

.picker-popup {
  background-color: #fff;
  border-radius: 20rpx 20rpx 0 0;
  max-height: 70vh;
  display: flex;
  flex-direction: column;
}

.popup-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 30rpx 40rpx;
  border-bottom: 2rpx solid #f0f0f0;
}

.popup-title {
  font-size: 32rpx;
  font-weight: 500;
  color: #333;
}

.close-btn {
  font-size: 36rpx;
  color: #999;
  padding: 10rpx;
}

.popup-content {
  flex: 1;
  max-height: 50vh;
}

.department-list {
  padding: 20rpx 0;
}

.department-item {
  display: flex;
  align-items: center;
  padding: 24rpx 30rpx;
  border-bottom: 2rpx solid #f8f8f8;
  transition: all 0.3s ease;
  opacity: 1;
  transform: translateY(0);
}

.department-name {
  flex: 1;
  margin-left: 20rpx;
  color: #333;
  font-size: 28rpx;
}

.department-name.has-children {
  color: #007aff;
}

.expand-icon {
  margin-left: 20rpx;
  display: flex;
  align-items: center;
  transition: transform 0.3s ease;
}

.expand-icon.expanded {
  transform: rotate(180deg);
}

.popup-footer {
  display: flex;
  padding: 30rpx 40rpx;
  border-top: 2rpx solid #f0f0f0;
  gap: 30rpx;
}

.cancel-btn,
.confirm-btn {
  flex: 1;
  border-radius: 8rpx;
  font-size: 28rpx;
  padding: 8rpx 0;
}

.cancel-btn {
  background-color: #f8f8f8;
  color: #666;
  border: none;
}

.confirm-btn {
  background-color: #007aff;
  color: #fff;
  border: none;
}
</style>
